/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.service.company.impl;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.auth.impl.Company;
import com.je.common.base.DynaBean;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.util.ArrayUtils;
import com.je.common.base.util.JEUUID;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.rbac.exception.CompanyException;
import com.je.rbac.rpc.CompanyRpcService;
import com.je.rbac.service.IconType;
import com.je.rbac.service.company.RbacCompanyService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


@Service
public class RbacCompanyServiceImpl implements RbacCompanyService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private CompanyRpcService companyRpcService;
    @Autowired
    private CommonService commonService;

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, CompanyException.class})
    public DynaBean doSave(DynaBean dynaBean) throws CompanyException{
        //若非根绝点则判断上级状态

        String sysParent = Strings.isNullOrEmpty(dynaBean.getStr("SY_PARENT"))? "ROOT" : dynaBean.getStr("SY_PARENT");
        int currentChildCount = 0;
        List<Map<String,Object>> currentChildList = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) AS MAX_COUNT FROM JE_RBAC_VCOMPANYDEPT WHERE SY_PARENT = {0}",sysParent);
        if(currentChildList.size()>0){
            currentChildCount = (int) currentChildList.get(0).get("MAX_COUNT");
        }

        String companyId = JEUUID.uuid();
        dynaBean.set("JE_RBAC_COMPANY_ID", companyId);
        dynaBean.set("SY_STATUS", "1");
        if(!Strings.isNullOrEmpty(dynaBean.getStr("SY_PARENT")) && dynaBean.getStr("SY_PARENT").equals("ROOT")){
            dynaBean.setStr("SY_GROUP_COMPANY_ID","ROOT");
            dynaBean.setStr("SY_GROUP_COMPANY_NAME","");

            //为空则为顶级集团公司节点
            String path = "/ROOT/" + companyId;
            String  treeOderIndex= "000001" + String.format("%06d", currentChildCount+1);
            String icon = IconType.TCONTYPE_GROUP.getVal();
            if(dynaBean.getStr("COMPANY_LEVEL_CODE").equals("COMPANY")){
                icon = IconType.TCONTYPE_COMPANY.getVal();
            }
            dynaBean = buildCompanyTreeNodeModel(dynaBean,"ROOT","/ROOT","1","LEAF",path,treeOderIndex,icon);
        }else{
            DynaBean parentBean = metaService.selectOne("JE_RBAC_COMPANY", ConditionsWrapper.builder().eq("JE_RBAC_COMPANY_ID", dynaBean.getStr("SY_PARENT")));
            if(parentBean == null){
                throw new CompanyException("不存在的父级公司，请确认父级公司存在！");
            }else{
                if(Strings.isNullOrEmpty(dynaBean.getStr("COMPANY_LEVEL_CODE"))){
                    throw new CompanyException("公司级别参数设置有误！");
                }
                if(!dynaBean.getStr("COMPANY_LEVEL_CODE").equals("GROUP_COMPANY") && !dynaBean.getStr("COMPANY_LEVEL_CODE").equals("COMPANY")){
                    throw new CompanyException("公司级别参数设置有误！");
                }
                //若父级为公司，该公司级别不能为集团公司
                if(parentBean.getStr("COMPANY_LEVEL_CODE").equals("COMPANY") && dynaBean.getStr("COMPANY_LEVEL_CODE").equals("GROUP_COMPANY")){
                    throw new CompanyException("公司级别下无法创建集团公司！");
                }
                //若父级为公司，该公司级别不能为公司
                if(parentBean.getStr("COMPANY_LEVEL_CODE").equals("COMPANY") && dynaBean.getStr("COMPANY_LEVEL_CODE").equals("COMPANY")){
                    throw new CompanyException("公司级别下无法创建公司！");
                }
                if(dynaBean.getStr("COMPANY_LEVEL_CODE").equals("COMPANY")){
                    dynaBean.set("COMPANY_ICON", IconType.TCONTYPE_COMPANY.getVal());
                }else{
                    dynaBean.set("COMPANY_ICON", IconType.TCONTYPE_GROUP.getVal());
                }
                metaService.executeSql("UPDATE JE_RBAC_COMPANY SET SY_NODETYPE='GENERAL' WHERE JE_RBAC_COMPANY_ID = {0}", parentBean.getStr("JE_RBAC_COMPANY_ID"));

                //设置公司数据
                dynaBean.setStr("SY_GROUP_COMPANY_ID",parentBean.getStr("JE_RBAC_COMPANY_ID"));
                dynaBean.setStr("SY_GROUP_COMPANY_NAME",parentBean.getStr("COMPANY_NAME"));

                dynaBean.set("SY_PARENT", parentBean.getStr("JE_RBAC_COMPANY_ID"));
                dynaBean.set("SY_PARENTPATH", parentBean.getStr("SY_PATH"));
                dynaBean.set("SY_LAYER", parentBean.getInt("SY_LAYER") + 1);
                dynaBean.set("SY_NODETYPE", "LEAF");
                dynaBean.set("SY_PATH", parentBean.getStr("SY_PATH") + "/" + companyId);
                dynaBean.set("SY_TREEORDERINDEX", parentBean.getStr("SY_TREEORDERINDEX") + String.format("%06d", currentChildCount+1));
            }
        }
        dynaBean.set("SY_ORDERINDEX",currentChildCount+1);
        commonService.buildModelCreateInfo(dynaBean);
        metaService.insert(dynaBean);
        return dynaBean;
    }


    public DynaBean buildCompanyTreeNodeModel(DynaBean dynaBean ,String parent , String parentPath, String layey , String nodetype , String path , String treeOderIndex , String icon){
        dynaBean.set("SY_PARENT", parent);
        dynaBean.set("SY_PARENTPATH", parentPath);
        dynaBean.set("SY_LAYER", layey);
        dynaBean.set("SY_NODETYPE", nodetype);
        dynaBean.set("SY_PATH", path);
        dynaBean.set("SY_TREEORDERINDEX", treeOderIndex);
        dynaBean.set("COMPANY_ICON", icon);
        return dynaBean;
    }

    @Override
    public boolean checkCompanyNameUnique(DynaBean dynaBean) {
        long count = 0;
        if(Strings.isNullOrEmpty(dynaBean.getStr("JE_RBAC_COMPANY_ID"))){
            count = metaService.countBySql(ConditionsWrapper.builder().table("JE_RBAC_COMPANY").eq("COMPANY_NAME", dynaBean.getStr("COMPANY_NAME")));
        }else{
            count = metaService.countBySql(ConditionsWrapper.builder().apply("SELECT * FROM JE_RBAC_COMPANY WHERE JE_RBAC_COMPANY_ID != {0} AND (COMPANY_NAME = {1})",dynaBean.getStr("JE_RBAC_COMPANY_ID"),dynaBean.getStr("COMPANY_NAME")));
        }
        if (count > 0) {
            return false;
        }
        return true;
    }

    @Override
    public boolean checkCompanyCodeUnique(DynaBean dynaBean) {
        long count = 0;
        if(Strings.isNullOrEmpty(dynaBean.getStr("JE_RBAC_COMPANY_ID"))){
            count = metaService.countBySql(ConditionsWrapper.builder().table("JE_RBAC_COMPANY").eq("COMPANY_CODE", dynaBean.getStr("COMPANY_CODE")));
        }else{
            count = metaService.countBySql(ConditionsWrapper.builder().apply("SELECT * FROM JE_RBAC_COMPANY WHERE JE_RBAC_COMPANY_ID != {0} AND (COMPANY_CODE = {1})",dynaBean.getStr("JE_RBAC_COMPANY_ID"),dynaBean.getStr("COMPANY_CODE")));
        }
        if (count > 0) {
            return false;
        }
        return true;
    }

    @Override
    public void checkCompanyLevelCode(DynaBean dynaBean) throws CompanyException {
        if(Strings.isNullOrEmpty(dynaBean.getStr("COMPANY_LEVEL_CODE"))){
            throw new CompanyException("公司层级参数有误，请检查！");
        }
        DynaBean companyBean = metaService.selectOne("JE_RBAC_COMPANY",ConditionsWrapper.builder().eq("JE_RBAC_COMPANY_ID",dynaBean.getStr("JE_RBAC_COMPANY_ID")));
        if(companyBean.getStr("COMPANY_LEVEL_CODE").equals("GROUP_COMPANY") && dynaBean.getStr("COMPANY_LEVEL_CODE").equals("COMPANY")){
            throw new CompanyException("集团不允许修改为公司，请检查！");
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, CompanyException.class})
    public void updateCompanyName(DynaBean dynaBean) throws CompanyException {
        DynaBean companyBean = companyRpcService.findById(dynaBean.getStr("JE_RBAC_COMPANY_ID"));
        if(!dynaBean.getStr("COMPANY_NAME").equals(companyBean.getStr("COMPANY_NAME"))){
            //修改公司表，部门表，部门人员表，账号部门关联表 公司名称
            //修改监管公司名称
            List<DynaBean> listBean = metaService.select("JE_RBAC_COMPANY",ConditionsWrapper.builder().like("COMPANY_JGCOMPANY_ID","%"+dynaBean.getStr("JE_RBAC_COMPANY_ID")+"%"));
            if(listBean!=null && listBean.size()>0){
                for(DynaBean eachCompanyBean : listBean){
                    List<String> jgIdList = Arrays.asList(eachCompanyBean.getStr("COMPANY_JGCOMPANY_ID").split(ArrayUtils.SPLIT));
                    List<String> jgNameList = Arrays.asList(eachCompanyBean.getStr("COMPANY_JGCOMPANY_NAME").split(ArrayUtils.SPLIT));
                    int indexCount = jgIdList.indexOf(companyBean.getStr("JE_RBAC_COMPANY_ID"));
                    jgNameList.set(indexCount,dynaBean.getStr("COMPANY_NAME"));
                    metaService.executeSql("UPDATE JE_RBAC_COMPANY SET COMPANY_JGCOMPANY_NAME={0} WHERE JE_RBAC_COMPANY_ID={1} ",StringUtils.join(jgNameList,","), eachCompanyBean.getStr("JE_RBAC_COMPANY_ID"));
                }
            }

            metaService.executeSql("UPDATE JE_RBAC_DEPARTMENT SET SY_COMPANY_NAME={0} WHERE SY_COMPANY_ID = {1}", dynaBean.getStr("COMPANY_NAME"),dynaBean.getStr("JE_RBAC_COMPANY_ID"));
            metaService.executeSql("UPDATE JE_RBAC_DEPARTMENT SET SY_GROUP_COMPANY_NAME={0} WHERE SY_GROUP_COMPANY_ID = {1}", dynaBean.getStr("COMPANY_NAME"),dynaBean.getStr("JE_RBAC_COMPANY_ID"));

            metaService.executeSql("UPDATE JE_RBAC_DEPTUSER SET SY_COMPANY_NAME={0} WHERE SY_COMPANY_ID = {1}", dynaBean.getStr("COMPANY_NAME"),dynaBean.getStr("JE_RBAC_COMPANY_ID"));
            metaService.executeSql("UPDATE JE_RBAC_DEPTUSER SET SY_GROUP_COMPANY_NAME={0} WHERE SY_GROUP_COMPANY_ID = {1}", dynaBean.getStr("COMPANY_NAME"),dynaBean.getStr("JE_RBAC_COMPANY_ID"));

            metaService.executeSql("UPDATE JE_RBAC_ACCOUNTDEPT SET SY_COMPANY_NAME={0} WHERE SY_COMPANY_ID = {1}", dynaBean.getStr("COMPANY_NAME"),dynaBean.getStr("JE_RBAC_COMPANY_ID"));
            metaService.executeSql("UPDATE JE_RBAC_ACCOUNTDEPT SET SY_GROUP_COMPANY_NAME={0} WHERE SY_GROUP_COMPANY_ID = {1}", dynaBean.getStr("COMPANY_NAME"),dynaBean.getStr("JE_RBAC_COMPANY_ID"));
        }
        if(!dynaBean.getStr("COMPANY_CODE").equals(companyBean.getStr("COMPANY_CODE"))){
            metaService.executeSql("UPDATE JE_RBAC_DEPTUSER SET SY_COMPANY_CODE={0} WHERE SY_COMPANY_ID = {1}", dynaBean.getStr("COMPANY_CODE"),dynaBean.getStr("JE_RBAC_COMPANY_ID"));
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, CompanyException.class})
    public void updateCompanyIcon(DynaBean dynaBean) throws CompanyException {
        metaService.executeSql("UPDATE JE_RBAC_COMPANY SET COMPANY_ICON={0} WHERE JE_RBAC_COMPANY_ID = {1}", IconType.TCONTYPE_GROUP.getVal(),dynaBean.getStr("JE_RBAC_COMPANY_ID"));
    }

    @Override
    public boolean updateCheckUnique(DynaBean orgBean) {
        String companyName = orgBean.getStr("COMPANY_NAME");
        String companyCode = orgBean.getStr("COMPANY_CODE");
        String tableId = orgBean.getStr("JE_RBAC_COMPANY_ID");
        long count = metaService.countBySql(ConditionsWrapper.builder().apply("SELECT * FROM JE_RBAC_COMPANY WHERE JE_RBAC_COMPANY_ID != {0} AND (COMPANY_NAME = {1} or COMPANY_CODE = {2})",tableId,companyName,companyCode));
        if (count > 0) {
            return false;
        }
        return true;
    }

    @Override
    public Boolean findGroupCompanyStatus(String companyIds) throws  CompanyException{
        List<String> idList = Splitter.on(",").splitToList(companyIds);
        List<DynaBean> companyBeans = metaService.select("JE_RBAC_COMPANY",ConditionsWrapper.builder().in("JE_RBAC_COMPANY_ID",idList));
        List<String> groupIdList = new ArrayList<>();
        for(DynaBean eachBean : companyBeans){
            groupIdList.add(eachBean.getStr("SY_GROUP_COMPANY_ID"));
        }
        List<DynaBean> groupCompanyBeans = metaService.select("JE_RBAC_COMPANY",ConditionsWrapper.builder().in("JE_RBAC_COMPANY_ID",groupIdList));
        for (DynaBean eachBean : groupCompanyBeans) {
            if(eachBean.getStr("SY_STATUS").equals("0")){
                if(idList.size() == 1){
                    throw new CompanyException("该公司上级公司已被禁用，请先启用！");
                }else{
                    throw new CompanyException("该公司的上级公司【"+eachBean.getStr("COMPANY_NAME")+"】已被禁用，请先启用！");
                }
            }
        }
        return true;
    }

    @Override
    public boolean checkChildCompany(String companyIds) {
        List<String> idList = Splitter.on(",").splitToList(companyIds);
        long childCompanyCount = metaService.countBySql(ConditionsWrapper.builder().table("JE_RBAC_COMPANY").in("SY_GROUP_COMPANY_ID", idList));
        if (childCompanyCount>0) {
            return false;
        }
        return true;
    }

    @Override
    public boolean checkChildDept(String companyIds) {
        List<String> idList = Splitter.on(",").splitToList(companyIds);
        long deptCount = metaService.countBySql(ConditionsWrapper.builder().table("JE_RBAC_DEPARTMENT").in("SY_COMPANY_ID", idList));
        if (deptCount > 0) {
            return false;
        }
        return true;
    }

    /**
     * 根据id查找Model
     * @param id
     * @return
     */
    @Override
    public Company findCompanyModelById(String id){
        DynaBean companyBean = companyRpcService.findById(id);
        Company company = new Company();
        company.parse(companyBean.getValues());
        return company;
    }

    /**
     * 根据Code查找Model
     * @param code
     * @return
     */
    @Override
    public Company findCompanyModelByCode(String code){
        DynaBean companyBean = companyRpcService.findByCode(code);
        Company company = new Company();
        company.parse(companyBean.getValues());
        return company;
    }

    /**
     * 根据Code查找Model
     * @param name
     * @return
     */
    @Override
    public Company findCompanyModelByName(String name){
        DynaBean companyBean = companyRpcService.findByName(name);
        Company company = new Company();
        company.parse(companyBean.getValues());
        return company;
    }

    /**
     * 根据Code查找Model
     * @param id
     * @return
     */
    @Override
    public Company findCompanyModelByParent(String id){
        DynaBean companyBean = companyRpcService.findParent(id);
        Company company = new Company();
        company.parse(companyBean.getValues());
        return company;
    }

    /**
     * 根据Code查找Model
     * @param id
     * @return
     */
    @Override
    public Company findCompanyModelAncestors(String id){
        DynaBean companyBean = companyRpcService.findAncestors(id);
        Company company = new Company();
        company.parse(companyBean.getValues());
        return company;
    }

    @Override
    public List<DynaBean> findByTenantId(String tenantId) {
        return metaService.select("JE_RBAC_COMPANY", ConditionsWrapper.builder().eq("SY_TENANT_ID", tenantId));
    }

    @Override
    public List<DynaBean> findByTenantName(String tenantName) {
        return metaService.select("JE_RBAC_COMPANY", ConditionsWrapper.builder().eq("SY_TENANT_NAME", tenantName));
    }

}
